home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-17 / dosdev.zip / STKDEV.ASM < prev    next >
Assembly Source File  |  1993-01-04  |  8KB  |  254 lines

  1. ; Listing 2 - STKDEV.ASM
  2. ;** PC-DOS Device Driver  - Reconfigurable Stack for Structures ( 1-32K bytes)
  3. ;
  4. ;   Bruce Bordner, 1985
  5. ;
  6. ;
  7. CSEG    SEGMENT PARA PUBLIC 'CODE'
  8. ;
  9. yell  macro char
  10.   push  es
  11.   push  di
  12.   push  ax
  13.   mov ax,'&char'
  14.   les di,CS:bugout
  15.   stos  byte ptr [di]
  16.   inc di
  17.   mov word ptr CS:bugout,di
  18.   pop ax
  19.   pop di
  20.   pop es
  21. endm
  22. ;
  23. XSTK    PROC FAR
  24.     ASSUME CS:CSEG,DS:CSEG,ES:CSEG
  25. BEGIN:
  26. START   EQU $
  27. ;  Header for DOS Device Drivers
  28. NEXT_DEV  DD  -1         ; fake pointer to next device driver
  29. ATTRIBUTE DW  0C000H     ;character device with IOCTL capability
  30. STRATEGY  DW  XSTK_STRAT ;pointer to function which queues request header
  31. FUNC_CALL DW  XSTK_FUNC  ;pointer to operating functions switch
  32. DEV_NAME  DB  'XSTK    ' ;8-byte device name field
  33. ;
  34. ;  Pointer to function request from DOS
  35. RH_OFF    DW  ?
  36. RH_SEG    DW  ?
  37. ;
  38. ;    Function Address Table for DOS Requests
  39. FUNTAB    LABEL  BYTE
  40.     DW  INIT    ; initialize device
  41.     DW  MEDIA_CHECK ; do a media check (block dev only)
  42.     DW  BUILD_BPB ; build BPB       "    "   "
  43.     DW  IOCTL_IN  ; IOCTL input
  44.     DW  INPUT   ; normal input (read device)
  45.     DW  ND_INPUT  ; non-destructive input no wait
  46.     DW  IN_STAT   ; report input status
  47.     DW  IN_FLUSH  ; flush input
  48.     DW  OUTPUT    ; output (write to device)
  49.     DW  OUT_VERIFY  ; output with verify
  50.     DW  OUT_STAT  ; report output status
  51.     DW  OUT_FLUSH ; flush output
  52.     DW  IOCTL_OUT ; IOCTL output
  53. ;
  54. bugout    dd   0B8000000h   ; screen address for yell macro
  55. ;
  56. ; Internal Data
  57. BOTMEM    DW  ?  ; start of stack storage space
  58. TOPMEM    DW  ?  ; end of storage (BOTMEM + 32K)
  59. RECSIZE   DW  ?  ; size of each structure to store, in bytes
  60. CURRENT   DW  ?  ; address after current "top of stack" - free spot
  61. NUM2READ  DW  0  ; number of bytes left to read to make full recsize
  62. NUM2WRITE DW  0  ; number left to write
  63. ; *end local data
  64. ;
  65. ;
  66. ;
  67. ;  Device Strategy - set pointer to request header from DOS
  68. XSTK_STRAT: MOV  CS:RH_SEG,ES
  69.     MOV  CS:RH_OFF,BX
  70.     RET
  71. ;
  72. ;  Device Interrupt Handler
  73. XSTK_FUNC:  ;preserve machine state
  74.     PUSHF
  75.     CLD
  76.     PUSH  DS
  77.     PUSH  ES
  78.     PUSH  AX
  79.     PUSH  BX
  80.     PUSH  CX
  81.     PUSH  DX
  82.     PUSH  DI
  83.     PUSH  SI
  84. ;      Set DS to CS value
  85.     PUSH  CS
  86.     POP   DS
  87. ;      Load ES and BX with RH_SEG and RH_OFF
  88.     LES   BX,DWORD PTR CS:RH_OFF
  89. ;      Branch to correct function in FUNTAB based on function code from DOS
  90.     MOV   AL,ES:[BX+2]  ; get function code byte
  91.     XOR   AH,AH
  92.     SHL   AL,1    ; make it into offset into FUNTAB
  93.     LEA   DI,FUNTAB   ; get address of FUNTAB base
  94.     ADD   DI,AX
  95.     JMP   WORD PTR[DI]  ; jump to function code
  96. ;
  97. ;
  98. ;
  99. ;   Functions not supported:
  100. ;
  101. MEDIA_CHECK:
  102. BUILD_BPB:
  103. ND_INPUT:
  104. OUT_VERIFY:
  105.     MOV ES:WORD PTR [BX+3],0100H  ; set status DONE, NOERROR
  106.     JMP EXIT
  107. ;************************************************************
  108. ;
  109. ;  Device Initialization
  110. INIT:   MOV  AX,OFFSET STORAGE
  111.     MOV  BOTMEM,AX    ; set lower limit
  112.     MOV  CURRENT,AX   ; set current record address
  113.     ADD  AX,32768   ; add 32K for top limit
  114.     MOV  TOPMEM,AX
  115.     MOV  ES:[BX+14],AX  ; return end of XSTK space
  116.     MOV  ES:[BX+16],CS  ;   and segment into request hdr
  117.     MOV  RECSIZE,1    ; default recsize = 1 byte
  118.     MOV  WORD PTR ES:[BX+3],0100H ;set status word to DONE, NOERROR
  119.     JMP  EXIT
  120. ;
  121. ;************************************************************
  122. ;
  123. IOCTL_IN:      ; report record size
  124.     MOV CX,WORD PTR ES:[BX+18]  ; get #bytes requested
  125.     LEA SI,RECSIZE
  126.     LES DI,DWORD PTR ES:[BX+14]
  127. REP   MOVSB
  128.     LES BX,DWORD PTR CS:RH_OFF
  129.     MOV ES:WORD PTR [BX+3],0100H  ; set status DONE, NOERROR
  130.     JMP EXIT
  131. ;************************************************************
  132. IOCTL_OUT:     ; change record size
  133.     MOV CX,WORD PTR ES:[BX+18]
  134.     LEA DI,RECSIZE
  135.     PUSH DS
  136.     LDS SI,DWORD PTR ES:[BX+14]
  137.     POP ES
  138. REP   MOVSB
  139.     LES BX,DWORD PTR CS:RH_OFF
  140.     MOV ES:WORD PTR [BX+3],0100H  ; set status DONE, NOERROR
  141.     JMP EXIT
  142. ;************************************************************
  143. ;
  144. IN_STAT:
  145. OUT_STAT:      ; BUSY if any records stacked, DONE if empty?
  146.     MOV ES:WORD PTR [BX+3],0100H  ; set status DONE, NOERROR
  147.     JMP EXIT
  148. ;************************************************************
  149. ;
  150. IN_FLUSH:
  151. OUT_FLUSH:     ; empty stack
  152.     MOV ES:WORD PTR [BX+3],0100H  ; set status DONE, NOERROR
  153.     JMP EXIT
  154. ;************************************************************
  155. ; Primary I/O Functions
  156. ;
  157. ; ES:[BX]+14 = offset of buffer in calling program
  158. ; ES:[BX]+16 = segment of buffer
  159. ; ES:[BX]+18 = size of buffer
  160. ;
  161. ;
  162. ;
  163. INPUT:    ; pop record from stack to calling program's buffer
  164.   yell R
  165.     CMP  NUM2WRITE,0
  166.     JE   CHKRED
  167.     MOV  AX,NUM2WRITE ;OUTPUT didn't push full record - adj CURRENT
  168.     ADD  CURRENT,AX  ; set to record boundary, end of last rec writ
  169. CHKRED:   MOV  SI,CURRENT     ; set SI to next byte position
  170.     CMP  NUM2READ,0   ; any bytes left to read to fill RECSIZE?
  171.     JG   PULLIT
  172.   yell n
  173.     MOV  AX,RECSIZE    ; starting a new record
  174.     MOV  NUM2READ,AX
  175.     SUB  SI,RECSIZE        ; sub record size from CURRENT
  176.     CMP  SI,BOTMEM         ; make sure full record can be pulled
  177.     JGE  PULLIT
  178.     MOV  WORD PTR ES:[BX+3],8130H ; else error 30H, stack empty
  179.     MOV  WORD PTR ES:[BX+18],0  ; no bytes transferred
  180.   yell e
  181.     JMP  EXIT
  182. PULLIT:   MOV  CX,WORD PTR ES:[BX+18] ; #bytes to move(ALWAYS 1,DOS 2.0)
  183.     SUB  NUM2READ,CX
  184.     MOV  DI,WORD PTR ES:[BX+14] ; get buffer offset + seg
  185.     MOV  AX,WORD PTR ES:[BX+16]
  186.     MOV  ES,AX
  187. REP   MOVSB     ; copy record to program buffer from stack at SI
  188.     CMP  NUM2READ,0     ; are we done with a record
  189.     JG   NEWPTR
  190.     SUB  SI,CS:RECSIZE    ; reset to record start
  191.   yell d
  192. NEWPTR:   MOV  CS:CURRENT,SI     ; SI has been incr by CX in MOVSB
  193.     LES  BX,DWORD PTR CS:RH_OFF ; reset to DOS request header
  194.     MOV  WORD PTR ES:[BX+3],0100H  ; set DONE, NOERROR
  195.     JMP  EXIT
  196. ;*************************************************************
  197. ;
  198. OUTPUT:   ; push record from calling program buffer onto stack storage
  199.   yell W
  200.     CMP  NUM2READ,0
  201.     JE   CHKWRIT
  202.     MOV  AX,RECSIZE  ; INPUT didn't take full record - adj CURRENT
  203.     SUB  AX,NUM2READ
  204.     SUB  CURRENT,AX  ; set to record boundary
  205. CHKWRIT:  MOV  DI,CURRENT     ; set DI to next byte position
  206.     CMP  NUM2WRITE,0   ; any bytes left to write to fill RECSIZE?
  207.     JG   STUFFIT
  208.   yell n
  209.     MOV  AX,RECSIZE    ; starting a new record
  210.     MOV  NUM2WRITE,AX
  211.     MOV  DX,DI
  212.     ADD  DX,RECSIZE     ; add record size to CURRENT
  213.     CMP  TOPMEM,DX         ; make sure full record can be stored
  214.     JNG  STUFFIT
  215.     MOV  WORD PTR ES:[BX+3],8120H ; else error 20H, stack full
  216.     MOV  WORD PTR ES:[BX+18],0  ; no bytes transferred
  217.   yell f
  218.     JMP  EXIT
  219. STUFFIT:  MOV  CX,WORD PTR ES:[BX+18] ; #bytes to move(ALWAYS 1,DOS 2.0)
  220.     SUB  NUM2WRITE,CX
  221.     PUSH  DS      ; need this for ES later
  222.     LDS  SI,DWORD PTR ES:[BX+14]  ; get buffer offset + seg
  223.     POP  ES   ; set to old DS value to reference stack space
  224. REP   MOVSB     ; copy record from program buffer to stack at DI
  225.     MOV  CS:CURRENT,DI     ; DI has been incr by CX in MOVSB
  226.     LES  BX,DWORD PTR CS:RH_OFF ; reset to DOS request header
  227.     MOV  WORD PTR ES:[BX+3],0100H  ; set DONE, NOERROR
  228.     JMP  EXIT
  229. ;*********************************************************
  230. ;
  231. ;  Restore registers and exit
  232. EXIT:   POP  SI
  233.     POP  DI
  234.     POP  DX
  235.     POP  CX
  236.     POP  BX
  237.     POP  AX
  238.     POP  ES
  239.     POP  DS
  240.     POPF
  241.     RET
  242. ;
  243. ;
  244. ; Align stack storage to start on a paragraph boundary - fits all storage types
  245.    if ($-START) MOD 16
  246. ORG   ($-START)+16-(($-START) MOD 16)
  247.    endif
  248. ;
  249. STORAGE   EQU $ ; start of stack storage space
  250. ;
  251. XSTK    ENDP
  252. CSEG    ENDS
  253.     END  BEGIN
  254.